package kvoog.arkanoid.common;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import com.artemis.Component;

/**
 * This component provider always returns the same instance of the component. The instance
 * is created when first required and is of the type passed in to the constructor.
 * 
 *  Ported from Ash entity component system framework for Action Script by Igor Knezevic. 
 * http://www.richardlord.net/blog/finite-state-machines-with-ash
 */
public class ComponentSingletonProvider implements IComponentProvider {

	private Class<? extends Component> componentType;
	private Component instance;
	
	/**
	 * Constructor
	 *
	 * @param type The type of the single instance
	 */
	public ComponentSingletonProvider(Class<? extends Component> type) {
		componentType = type;
	}

	/**
	 * Used to request a component from this provider
	 *
	 * @return The single instance
	 */
	@Override
	public Component getComponent() {
		if (instance == null) {
			try {
				Constructor<? extends Component> ctor = componentType.getConstructor();
				instance = ctor.newInstance();
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return instance;
	}

	/**
	 * Used to compare this provider with others. Any provider that returns the same single
	 * instance will be regarded as equivalent.
	 *
	 * @return The single instance
	 */
	@Override
	public int getId() {
		// TODO Not yet implemented !
		return 0;
	}

}
